﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Tree.Process;
using System.Security.Principal;
using System.ServiceProcess;
using Tree.Factory;
using Tree.Container;
using System.Reflection;
using log4net;
namespace Tree.Runner
{
    /// <summary>
    /// Application wrapped entry point.
    /// </summary>
    public class Dromeas
    {
        private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        
        private const int ATTACH_PARENT_PROCESS = -1;

        [DllImport("kernel32", SetLastError = true)]
        public static extern bool AttachConsole(int dwProcessId);

        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();

        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();

        private bool isService = true;

        private bool isSilent = false;

        private static GraceAndMercy holder = new GraceAndMercy();

        public Dromeas()
        {
            System.Diagnostics.Process parentProcess = ProcessHelper.GetParentProcess();
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);

            isService &= parentProcess.ProcessName.ToLower().Contains("services");
            isService &= identity.IsSystem;

            if (!isSilent)
            {
                if (parentProcess.ProcessName.ToLower().Contains("cmd"))
                {
                    AttachConsole(ATTACH_PARENT_PROCESS);
                }
            }
        }

        public void Run()
        {
            if (isService)
            {
                AsService();
            }
            else
            {
                AsApplication();
            }            
        }

        public void Exit()
        {
            Core.Container.Stop();
            holder.Release();
        }

        private void AsApplication()
        {
            Core.Container.Start();
            holder.Hold();
        }

        private void AsService()
        {
            logger.Debug("Running as Service");

            WrappedService service = Core.Container.Register<WrappedService>() as WrappedService;

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
				service
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
}
